#include <time.h>
#include "logic.h"

static void* main_thread(void* arg);
static void* conn_thread(void* arg);
static void* recv_thread(void* arg);

LogicServer::LogicServer(const char* conf):m_config(conf),
    log(m_config.getString("LOG_PATH")),
    m_server(m_config.getInt("SERVER_PORT")),
    m_msg_pool(m_config.getInt("POOL_SIZE"))
{
    for(int i=0; i<LOG_NUM; i++){
        log.set(i, m_config.getInt(_LOG_NAME[i]));
    }

    m_is_server = m_config.getBool("IS_SERVER");
    m_is_client = m_config.getBool("IS_CLIENT");
    m_overtime = m_config.getInt("OVER_TIME");
    if(m_overtime < 0){
        m_overtime = LOGIC_DEF_OVERTIME;
    }
    m_version = m_config.getString("VERSION");
    m_conn_is_long = m_config.getBool("CONN_IS_LONG");
}

void LogicServer::run(){
    pthread_t t;

    // 检查是否连接到了dbserver
    if(m_is_client && !m_client.isConnected()){
        pthread_create(&t, NULL, &conn_thread, this);
    }

    pthread_create(&t, NULL, &main_thread, this);
    pthread_create(&t, NULL, &recv_thread, this);
    while(true){
    }
}

void LogicServer::main_run(){
    MongoClient client(m_config.getString("DB_IP"));
    while(true){
        WAMessage** ppmsg = m_msg_pool.pop();
        if(ppmsg != NULL){
            main_handle(client, (const WAMessage*)*ppmsg);
            if(!m_conn_is_long){
                close((*ppmsg)->fd);
            }
            delete *ppmsg;
        }
    }
}
void LogicServer::recv_run(){
    char buf[STREAM_BUF_SIZE] = {0};

    while(true){
        int fd = m_server.Accept();
        log.info("Accept[%d]", fd);
        int size = recv(fd, buf, STREAM_BUF_SIZE, 0);
        if(size > 0){
            log.debug("RECV DATA[%s]", buf);
            WAMessage* msg = new WAMessage(fd, buf, size);
            m_msg_pool.put(msg);
        }
        memset(buf, 0, STREAM_BUF_SIZE);
    }
}

static void* conn_thread(void* arg){
    LogicServer* logic = (LogicServer*) arg;
    while(!logic->isConnectServer()){
        logic->connectServer();
        sleep(5);
    }
}

static void* main_thread(void* arg){
    LogicServer* logic = (LogicServer*)arg;
    logic->main_run();
}

static void* recv_thread(void* arg){
    LogicServer* logic = (LogicServer*)arg;
    logic->recv_run();
}

